feat: Rust fd5 audit trail with identity and chain verification#173
Open
gerchowl wants to merge 2 commits intofeature/123-fd5-rust-cratefrom
Open
feat: Rust fd5 audit trail with identity and chain verification#173gerchowl wants to merge 2 commits intofeature/123-fd5-rust-cratefrom
gerchowl wants to merge 2 commits intofeature/123-fd5-rust-cratefrom
Conversation
…d chain verification Add test skeletons with todo!() stubs for: - audit.rs: serde roundtrip, read/write/append, malformed JSON - identity.rs: anonymous default, save/load roundtrip, to_author - edit.rs: audit entry creation, preservation, parent_hash, tamper detection - verify.rs: chain verification (valid, no log, broken chain, single entry) Refs: #167, #168, #169, #170 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…g, and chain verification All 19 tests pass (15 new + 4 existing): audit.rs: read/write audit log as JSON in _fd5_audit_log HDF5 attribute - read_audit_log returns empty vec when attr missing - append_audit_entry preserves existing entries - Malformed JSON returns clear Fd5Error::Json identity.rs: load/save identity from TOML files - anonymous() default when no config exists - load_from falls back to anonymous for missing files - to_author converts Identity -> Author for audit entries edit.rs: EditPlan::apply now creates audit entries automatically - Records parent_hash, timestamp, author, message, and changes - Audit log participates in Merkle tree (tamper-evident) - content_hash recomputed after audit entry is appended verify.rs: verify_chain reconstructs intermediate states - Reverses attribute edits to verify each parent_hash link - Detects broken chains with index, expected, and actual hashes - Thread-safe temp file handling with atomic counter Refs: #167, #168, #169, #170 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
audit.rs: tamper-evident audit log stored as JSON in_fd5_audit_logHDF5 attribute, withread_audit_log/append_audit_entryfunctions and cross-language-compatible JSON format matching the Python specidentity.rs: user identity loaded from~/.fd5/identity.toml(TOML format), with anonymous fallback andAuthorconversion for audit entriesedit.rs:EditPlannow carriesmessageandauthorfields;apply()automatically creates an audit entry withparent_hash, timestamp, author, message, and change details before recomputingcontent_hashverify_chaintoverify.rs: reconstructs intermediate file states by reversing recorded attribute edits to verify eachparent_hashlink in the audit chain, detecting broken chains with precise index/expected/actual diagnosticsImplementation details
_fd5_audit_log) is NOT inEXCLUDED_ATTRS, so it participates in the Merkle tree and any tampering is detected byverifyTest plan
cargo test -p fd5 --lib— all 19 tests passtest_audit_entry_serde— JSON roundtrip with correct field names (typenotauthor_type)test_read_empty_log— empty file returnsOk(vec![])test_write_read_roundtrip— append + read returns identical entrytest_append_preserves_existing— two appends yield both entriestest_malformed_json_error— bad JSON produces clear errortest_anonymous_default— anonymous identity has expected fieldstest_save_load_roundtrip— TOML save + load returns identical identitytest_missing_file_returns_anonymous— missing TOML falls back to anonymoustest_to_author_conversion— Identity to Author field mapping correcttest_edit_creates_audit_entry— edit produces audit log with 1 entrytest_edit_preserves_existing_log— two edits produce 2-entry logtest_audit_entry_has_correct_parent_hash— parent_hash matches pre-edit content_hashtest_content_hash_covers_audit_log— tampering audit log breaks Merkle verifytest_no_log_returns_nolog— file without audit log returnsChainStatus::NoLogtest_single_entry_valid— one edit validates asValid(1)test_valid_chain— two edits validate asValid(2)test_broken_chain_detected— fake entry with wrong parent_hash detected at correct indexCloses #167, closes #168, closes #169, closes #170
🤖 Generated with Claude Code